<?php

namespace app\service;


class SwooleServer
{
    private $serv;

    public function __construct()
    {
        $this->serv = new \swoole_server("127.0.0.1", 9502);

        $this->serv->set(
            [
                'worker_num' => 20, //一般设置为服务器CPU数的1-4倍
                'daemonize' => 1, //1以守护进程执行
                'max_request' => 50,
                'dispatch_mode' => 3,
                'task_worker_num' => 100, //task进程的数量
                'open_eof_check' => true,//打开EOF检测
                'package_eof' => "\r\n",//设置EOF
                'open_eof_split' => true
            ]
        );

        $this->serv->on("workerStart", [$this, 'onWorkerStart']);
        $this->serv->on('Receive', [$this, 'onReceive']);
        $this->serv->on('Task', [$this, 'onTask']);
        $this->serv->on('Finish', [$this, 'onFinish']);

        $this->serv->start();
    }

    /**
     * @param $server
     * @param $worker_id
     * @return void
     * @throws \Exception
     */
    public function onWorkerStart($server, $worker_id)
    {
        echo '[' . date('Y-m-d H:i:s') . '] ' . "onWorkerStart" . PHP_EOL;

        // 一个进程执行定时任务
        if ($worker_id == 0) {
            $this->cronJob();
        }

        // 定义应用目录
        define('DS', DIRECTORY_SEPARATOR);
        define('ROOT', realpath('../../') . DS);
        define('APP', ROOT . 'app' . DS);
        define('CORE', ROOT . 'core' . DS);

        // 引入自动加载
        require ROOT . 'vendor/autoload.php';

        // 自定义加载器
        require_once CORE . 'Base.php';

        spl_autoload_register('\core\Base::load');
        \core\Base::run();
    }

    public function onReceive($serv, $fd, $from_id, $data)
    {
        $serv->task($data);
    }

    public function onTask($serv, $task_id, $from_id, $data)
    {
        $data = json_decode($data, true);

    }

    public function onFinish($serv, $task_id, $data)
    {
        //echo "Task {$task_id} finish\n";  
        //echo "Result: {$data}\n";  
    }

    /*public function runStart()
    {

    }*/

    private function cronJob()
    {
        //初始化定时任务列表
        $cronPath = scandir(APP . 'cron');
        foreach ($cronPath as $file) {
            //目录跳过
            if (is_dir(APP . 'cron/' . $file)) {
                continue;
            }
            // 非php跳过
            $fileInfo = pathinfo($file);
            if ($fileInfo['extension'] != "php") {
                continue;
            }

            try {
                $fn = $fileInfo['filename'];
                $class = "\app\cron\{$fn}";
                $classObj = new $class();
                //循环的执行的多少秒执行一次
                if ($classObj->daemon) {
                    return;
                }

                $daemons = !is_array($classObj->daemon) ? [$classObj->daemon] : $classObj->daemon;
                foreach ($daemons as $daemon) {
                    $param = explode("_", $daemon);
                    $p = $param[1];
                    $interval = intval($param[0]);
                    swoole_timer_tick($interval * 1000, function ($timer_id) use ($fn, $p) {
                        $this->serv->task(json_encode(['m' => $fn, 'p' => $p]));
                    });
                    $data = array('startTime' => time(), 'interval' => $interval, 'cnt' => 0);
                    $this->serv->taskList['daemon'][$fn . '.' . $p] = $data;
                }
            } catch (\Exception $e) {
                // ...
            } catch (\Throwable $t) {
                // ...
            }
        }
    }
}  
  